<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <select name="" id="">
      <option value="0">请选择销量范围</option>
      <option value="1">&lt100</option>
      <option value="2">100~500</option>
      <option value="3">&gt500</option>
    </select>
    <ul>
      <li>牛客logo马克杯</li>
      <li>无盖星空杯</li>
      <li>老式茶杯</li>
      <li>欧式印花杯</li>
    </ul>

    <script>
        /**
         * 这题的封装自我感觉很满意，复用性杠杠的 
         * 两大亮点：
         * 1. priceRange以对象化封装调用函数
         * 2. rangejudgment考虑多种常用区间情况封装函数
         */
      var cups = [
        {
          type: 1,
          price: 100,
          color: "black",
          sales: 60,
          name: "牛客logo马克杯",
        },
        { type: 2, price: 40, color: "blue", sales: 100, name: "无盖星空杯" },
        { type: 4, price: 60, color: "green", sales: 200, name: "老式茶杯" },
        { type: 3, price: 50, color: "green", sales: 600, name: "欧式印花杯" },
      ];
      var select = document.querySelector("select");
      var ul = document.querySelector("ul");
      // 补全代码

      //价格区间判断函数组
      let priceRange = {
        0: (sales) => true,
        1: (sales) => rangejudgment(sales, 0, 100, 0),
        2: (sales) => rangejudgment(sales, 100, 500, 1),
        3: (sales) => rangejudgment(sales, 500, false, 2),
      };


      /**
       * 选项改变事件
       * 为什么不用箭头函数？因为需要this；
       * 为什么需要this？因为判题是直接调用的压根没有点击
       * 当然被我注释的方法也是可以的
       */
      select.onchange = function (e) {
        // let { value } = e.target;
        let value = this.value;
        let newList = cups.filter((item) => priceRange[value](item.sales));
        showList(newList, ul);
      };

      /**
       * 展示列表
       * @param {Array} list -列表
       * @param {HTMLElement} ul -ul元素
       * @returns {void}
       */
      function showList(list, ul) {
        ul.innerHTML = "";
        list.forEach((item) => {
          let li = document.createElement("li");
          li.innerHTML = item.name;
          ul.appendChild(li);
        });
      }

      /**
       * 范围判断
       * @param {number} value -用于比较的数值
       * @param {number|boolean} firstNum -第一个数值（小）-若无限小则为false
       * @param {number|boolean} secondNum -第二个数值（大）-若无限大则为false
       * @param {number} [type=0] -判断类型:0-左闭右开，1-左闭右闭，2-左开右开，3-左开右闭
       * @returns {boolean} -判断结果
       */
      const rangejudgment = (value, firstNum, secondNum, type = 0) => {
        try {
          switch (type) {
            case 0:
              return (
                (firstNum ? value >= firstNum : true) &&
                (secondNum ? value < secondNum : true)
              );
            case 1:
              return (
                (firstNum ? value >= firstNum : true) &&
                (secondNum ? value <= secondNum : true)
              );
            case 2:
              return (
                (firstNum ? value > firstNum : true) &&
                (secondNum ? value < secondNum : true)
              );
            case 3:
              return (
                (firstNum ? value > firstNum : true) &&
                (secondNum ? value <= secondNum : true)
              );
            default:
              throw new Error("type参数错误");
          }
        } catch (e) {
          console.log(e);
          return false;
        }
      };
    </script>
  </body>
</html>
